/**
 * The HEALTH class defines some utility methods
 */

var HEALTH_ROLE_PATIENT="Patient";
var HEALTH_ROLE_DOCTOR="Doctor";
var HEALTH_ROLE_HOSPITAL="Hospital";

var HEALTH = new function() {
	/**
	 * @private
	 */
	var role="";

	/**
	 * the main datatable object
	 * @private
	 */
	var mainDataTable;

	/**
	 * The controller url for surgery slots
	 * @const
	 */
	var slotsUrl = "reservation/slots";

	/**
	 * The controller url for messages
	 * @const
	 */
	var messageUrl = "notification/check";

	/**
	 * @const
	 */
	var FILTER_PLACEHOLDER_ID = "#_HEALTH_filter";

	/**
	 * adds options dynamically to the specified select
	 * @param url the data url (get request)
	 * @param selectId the id of the select element
	 */
	this.addOptions = function (url, selectId) {
		$.ajax({
			url:url,
			type:'GET',
			dataType: 'json',
			success: function(json) {
				$.each(json, function(i, value) {
					$('#' + selectId).append($('<option>').text(value).attr('value', value));
				});
			}
		});
	};

	/**
	 * adds options dynamically to the specified select
	 * @param url the data url (get request)
	 * @param selectId the id of the select element
	 * @param value the value to select
	 */
	this.addOptionsAndSetValue = function (url, selectId, value) {
		$.ajax({
			url:url,
			type:'GET',
			dataType: 'json',
			success: function(json) {
				$.each(json, function(i, value) {
					$('#' + selectId).append($('<option>').text(value).attr('value', value));
				});
				$('#' + selectId).val(value);
			}
		});
	};

	/**
	 * This function calls a server side "setter"
	 * @param url the url of the controller
	 * @param variables the variables to pass
	 */
	this.callSetter = function (url, variables) {
		$.ajax({
			url:url,
			async:false,
			type:'GET',
			data:variables,
			dataType: 'json'
		});
	};

	/**
	 * Adds a notification
	 * @param type the type (info, error, warning)
	 * @param title the title of the message
	 * @param text the notification text
	 */
	this.addNotification = function (type, title, text) {
		HEALTH.showNotification("alert-area", type, title, text);
	};

	/**
	 * Adds a auto dispose notification
	 * @param type the type (info, error, warning)
	 * @param title the title of the message
	 * @param text the notification text
	 */
	this.addAutoDisposeNotification = function (type, title, text) {
		HEALTH.showNotificationMessage("alert-area", type, title, text, true);
	};

	/**
	 * Shows a notification in the given target element
	 * @param target the target element's id
	 * @param type the type (info, error, warning)
	 * @param title the title of the message
	 * @param text the notification text
	 */
	this.showNotification = function (target, type, title, text) {
		HEALTH.showNotificationMessage(target, type, title, text, false);
	};

	/**
	 * Shows a notification in the given target element
	 * @param target the target element's id
	 * @param type the type (info, error, warning)
	 * @param title the title of the message
	 * @param text the notification text
	 * @param autoDispose true if the notification should be removed after a while
	 */
	this.showNotificationMessage = function (target, type, title, text, autoDispose) {
		var notificationId = Math.random().toString(36).substring(7);
		$("#" + target).append($("<div class='alert alert-" + type + "' id='msg" + notificationId + "'><button type='button' class='close' data-dismiss='alert' onclick='$(this).parent().remove();'>&times;</button><h4 class='alert-heading'>" + title + "</h4><p> " + text + " </p></div>"));
		if (autoDispose) {
			setTimeout(function() {
				$("#msg" + notificationId).remove();
			}, 5000);
		}
	};

	/**
	 * Register a notification handler
	 */
	this.registerNotificationHandler = function() {
		setInterval(HEALTH.checkNotifications, 5000);		
	};

	/**
	 * Performs check to retrieve new notifications
	 */
	this.checkNotifications = function() {
		$.ajax({
			url:messageUrl,
			type:'GET',
			dataType: 'json',
			success: function(json) {
				$.each(json, function(i, value) {
					HEALTH.addNotification(value.type, value.title, value.message);
				});
			}
		});
	};

	/**
	 * Reloads the datatable, i.e. clear the data and redraw the table
	 *
	 * @param dataTable the datatable object
	 * @param url the url to fetch the data
	 */
	this.reloadDataTable = function(dataTable, url) {
		if (dataTable != null) {
			//perform the ajax request
			$.ajax({
				dataType: "json",
				url: url,
				success: function(json) {
					//first clear the table
					dataTable.fnClearTable();
					for (var i = 0; i < json.length; i++) {
						//add the data without redrawing the table
						dataTable.fnAddData(json[i], false);
					}
					//at the end redraw
					dataTable.fnDraw();
				},
				error: function(jqXHR, textStatus, errorThrown) {
					HEALTH.addAutoDisposeNotification("error", "Fehler bei der Serverkommunikation", "Beim Laden der Daten ist ein Fehler aufgetreten. Bitte überprüfen Sie Ihre Internetverbindung");
				}
			});
		}
	};

	/**
	 * Does the default page initialization (create the main datatable and register the notification handler)
	 * @param mainDataGridId
	 * @param columns
	 */
	this.initPage = function(mainDataGridId, columns) {
		mainDataTable = HEALTH.createSlotTable(mainDataGridId, columns);
		HEALTH.createFilters();
		HEALTH.registerNotificationHandler();
		//create refresh timer for the main table
		setInterval(HEALTH.reloadMainTable, 7000);
	};

	/**
	 * @private
	 */
	this.createFilters = function() {
		var placeHolder = $(FILTER_PLACEHOLDER_ID);
		if (placeHolder.length > 0) {
			$(document).ready(function() {
				placeHolder.html('<div class="well form-inline pull-right" id="_HEALTH_FILTER_OBJECT"></div><br/><br/><br/><br/><br/>');
				var filterDiv = $("#_HEALTH_FILTER_OBJECT");
				var dateFilter = $('<label for="dateSelector">Datum</label><span class="input-append date datepicker" id="datepicker"><input name="dateFilter" type="text" id="dateSelector" data-format="dd.MM.yyyy"><span class="add-on"><i data-date-icon="icon-calendar"></i></span></span>');
				var departmentFilter = $('<label for="typeFilter">OP Typ</label><select id="typeFilter"></select>');
				var hospitalFilter = $('<label for="hospitalFilter">Krankenhaus</label><select id="hospitalFilter"></select>');
				var reservedFilter = $('<label for="stateFilter">Status</label><select id="stateFilter"><option/><option value="true">Frei</option><option value="false">Reserviert</option></select>');

				filterDiv.append(dateFilter);
				filterDiv.append(departmentFilter);
				if(HEALTH.role!=HEALTH_ROLE_HOSPITAL){
					filterDiv.append(hospitalFilter);
				} else{
					filterDiv.append(reservedFilter);
				}

				$('#datepicker').datetimepicker({
					pickTime: false
				}).on('changeDate', function (ev, date) {
						var d = (ev.date == undefined ? new Date() : ev.date).getTime();
						HEALTH.callSetter("filter", {'filterKey': "DATE", 'filterValue': d});
						HEALTH.reloadMainTable()
					});

				//set the date filter value if present in the session
				if (window["dateFilterValue"] != "" && HEALTH.isNumber(window["dateFilterValue"])) {
					var dateValue = new Date(window["dateFilterValue"] * 1);
					$('#dateSelector').val(dateValue.getDay() + "." + (dateValue.getMonth() + 1) + "." + dateValue.getFullYear());
				}
				//dynamically add the options to the selects
				HEALTH.addOptionsAndSetValue('department', 'typeFilter', window["typeFilterValue"]);
				HEALTH.addOptionsAndSetValue('hospital', 'hospitalFilter', window["hospitalFilterValue"]);
				
				//the change handlers
				$('#typeFilter').change(function() {
					HEALTH.callSetter("filter", {'filterKey':"SURGERY_TYPE",'filterValue':$('#typeFilter').val()});
					HEALTH.reloadMainTable();
				});
				$('#hospitalFilter').change(function() {
					HEALTH.callSetter("filter", {'filterKey':"HOSPITAL",'filterValue':$('#hospitalFilter').val()});
					HEALTH.reloadMainTable()
				});
				$('#stateFilter').change(function() {
					HEALTH.callSetter("filter", {'filterKey':"FREE",'filterValue':$('#stateFilter').val()});
					HEALTH.reloadMainTable()
				});
			});
		}
	};

	/**
	 * Reloads the main data table
	 */
	this.reloadMainTable = function() {
		HEALTH.reloadDataTable(mainDataTable, slotsUrl);
	};

	/**
	 * This functions creates a datatable for the specified DOM element (id) using the given columns to create
	 * the column definition.
	 *
	 * The data will be loaded automatically from the server side controller, i.e. this method can be used for every
	 * dashboard view.
	 *
	 * @param id
	 * @param columns
	 */
	this.createSlotTable = function (id, columns) {
		var columnData = [];
		//create the column properties array
		jQuery.each(columns, function (i, value) {
			if (value == null) {
				columnData.push({ "mData": null });
			} else if (typeof value == "string") {
				columnData.push({ "mDataProp": value });
			} else {
				//this is for functions
				columnData.push({ "mData": value });
			}
		});
		//create the datatable using the properties from above and some default settings
		//the datatable will be returned to allow modifications or updates directly on the js object without a
		//dom lookup
		return $('#' + id).dataTable({
			"bProcessing": false,
			"bPaginate": false,
			"bLengthChange": false,
			"bFilter": false,
			"bSort": false,
			"bInfo": false,
			"bAutoWidth": false,
			"sAjaxSource": slotsUrl,
			"sAjaxDataProp": "",
			"oLanguage": {
				"sEmptyTable": "Keine Daten zur Anzeige vorhanden"
			},
			"aoColumns": columnData
		});
	};

	/**
	 * Exports the given symbol as public property
	 * @param publicName the name of the property
	 * @param symbol the symbol to export
	 */
	this.exportSymbol = function(publicName, symbol) {
		window[publicName] = symbol;
	};

	/**
	 * Returns true if the given object is a number, otherwise false
	 * @param num the number
	 */
	this.isNumber = function(num) {
		return !isNaN(num);
	};

	/**
	 * Set the rolename
	 * @param rolename
	 */
	this.setRole = function(rolename) {
		HEALTH.role = rolename;
	};

	/**
	 * Returns the role
	 */
	this.getRole = function() {
		return HEALTH.role;
	};
};


//export the HEALTH class
HEALTH.exportSymbol('HEALTH', HEALTH);
HEALTH.exportSymbol('HEALTH.addNotification', HEALTH.addNotification);